package org.gvp.generator.core.writer.impl;

import org.gvp.generator.constant.ImportConstant;
import org.gvp.generator.core.writer.AbstractFileWriter;
import org.gvp.generator.props.CreateProps;
import org.gvp.generator.props.ProjectProps;
import org.gvp.generator.table.TableInfo;

import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * 数据层实现类代码生成类
 */
public class RepositoryImplFileWriter extends AbstractFileWriter {
    @Override
    public void execute(TableInfo tableInfo, ProjectProps project) {
        String upName = tableInfo.getUpperName();
        String classDefine = """
                /**
                 * %s 数据层接口实现类
                 */
                @Repository
                @RequiredArgsConstructor
                public class %sRepositoryImpl implements %sRepository { 
                    private final %sMapper %sMapper;
                """.formatted(tableInfo.getRemark(),upName,upName,upName,tableInfo.getLowerName());

        channel.writeNewline(project.getBasePackageImport() + project.getRepositoryPackage() + ".impl;");
        channel.writeEmptyLine();
        channel.writeNewline(ImportConstant.LOMBOK_REQ_CONS);
        channel.writeNewline(ImportConstant.SPRING_REPOSITORY);
        channel.writeNewline(ImportConstant.MYBATIS_PLUS_WRAPPER);
        channel.writeNewline(project.getBaseImport() + project.getRepositoryPackage() + "." + upName + "Repository;");
        channel.writeNewline(project.getBaseImport() + project.getMapperPackage() + "." + upName + "Mapper;");
        channel.writeNewline(project.getEntityImport());
        channel.writeNewline(ImportConstant.LIST);
        channel.writeNewline(classDefine);
        writeMethod(upName,tableInfo.getLowerName());
        channel.writeNewline("}");
    }

    private void writeMethod(String upName,String loName){
        String append = """
                    @Override
                    public int append(%s pojo) {
                        return this.%sMapper.insert(pojo);
                    }
                """.formatted(upName,loName);
        String modify = """
                    @Override
                    public int modify(%s pojo) {
                        return this.%sMapper.updateById(pojo);
                    }
                """.formatted(upName,loName);
        String cancel = """
                    @Override
                    public int cancel(Integer id) {
                        return this.%sMapper.deleteById(id);
                    }
                """.formatted(loName);
        String searchById = """
                    @Override
                    public %s searchById(Integer id) {
                        return this.%sMapper.selectById(id);
                    }
                """.formatted(upName,loName);
        String searchList = """
                    @Override
                    public List<%s> searchList() {
                        return this.%sMapper.selectList(null);
                    }
                """.formatted(upName,loName);
        String searchCount = """
                    @Override
                    public Long searchCount(String field) {
                        return this.%sMapper.selectCount(null);
                    }
                """.formatted(loName);
        String searchLimit = """
                    @Override
                    public List<%s> searchLimit(int start, int end) {
                        return this.%sMapper.selectList(Wrappers.<%s>lambdaQuery()
                                .last("LIMIT %s,%s".formatted(start,end))
                                .orderByDesc(%s::getOrder)
                                .orderByAsc(%s::getId)
                        );
                    }
                """.formatted(upName,loName,upName,"%d","%d",upName,upName);
        channel.writeNewline(append);
        channel.writeNewline(modify);
        channel.writeNewline(cancel);
        channel.writeNewline(searchById);
        channel.writeNewline(searchList);
        channel.writeNewline(searchCount);
        channel.writeNewline(searchLimit);
    }

    @Override
    public boolean isWriterFile(CreateProps create) {
        return create.isCreateRepositoryImpl();
    }

    @Override
    public Path getFilePath(String basePath, ProjectProps project, String fileName) {
        return Paths.get(basePath, project.getRepositoryPackage(),"impl",fileName + "RepositoryImpl.java");
    }
}
